package com.campus.controller.System;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.campus.common.config.CodeConfig;
import com.campus.common.constant.Constant;
import com.campus.entity.ResultBody;
import com.campus.entity.RoomManager;
import com.campus.entity.Student;
import com.campus.entity.System.SysUser;
import com.campus.entity.System.SysUserRole;
import com.campus.entity.Teacher;
import com.campus.mapper.SysUserMapper;
import com.campus.mapper.TeacherMapper;
import com.campus.service.*;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.security.Principal;
import java.util.*;

/**
 * @author Alaskaboo
 * @since 2022-10-23 14:42:37
 **/
@RestController
@RequestMapping("/api/user")
public class SysUserController {
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    private UploadService uploadService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private RoomManagerService roomManagerService;
    @Value("${qiniu.prefix}")
    private String prefix;

    @Autowired
    private SysUserMapper sysUserMapper;

    @GetMapping("/info")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResultBody userInfo(Principal principal) {
        Map<String, Object> resultMap = new HashMap<>();
        SysUser currentUser = sysUserService.getByAccount(principal.getName());
        resultMap.put("currentUser", currentUser);
        return ResultBody.ok().data(resultMap);
    }

    @PostMapping("/uploadAvatar")
    @CacheEvict(value = {"studentInfo", "teacherInfo", "roomManagerInfo"}, allEntries = true)
    public ResultBody userPhoto(MultipartFile multipartFile, String account) {
        //获取原始文件名
        String originalFilename = multipartFile.getOriginalFilename();
        int lastIndexOf = originalFilename.lastIndexOf(".");
        //获取文件后缀
        String suffix = originalFilename.substring(lastIndexOf + 1);
        //使用UUID随机产生文件名称，防止同名文件覆盖
        String uuid = UUID.randomUUID().toString();
        String fileName = uuid + "." + suffix;
        String imgSrc = prefix + "/" + fileName;
        try {
            Student student = studentService.lambdaQuery().in(Student::getAccount, account).one();
            Teacher teacher = teacherService.lambdaQuery().in(Teacher::getAccount, account).one();
            RoomManager roomManager = roomManagerService.lambdaQuery().in(RoomManager::getAccount, account).one();
            if (student != null) {
                student.setAvatar(imgSrc);
                studentService.updateById(student);
            }
            else if (roomManager != null) {
                roomManager.setAvatar(imgSrc);
                roomManagerService.updateById(roomManager);
            } else {
                teacher.setAvatar(imgSrc);
                teacherService.updateById(teacher);
            }
            uploadService.upload2Qiniu(multipartFile.getBytes(), fileName);
            return ResultBody.ok().data("imgSrc", imgSrc).message(CodeConfig.PIC_UPLOAD_SUCCESS.message);
        } catch (Exception e) {
            e.printStackTrace();
            //图片上传失败
            return ResultBody.error().message(CodeConfig.PIC_UPLOAD_FAIL.message);
        }
    }

    /**
     * 验证用户名
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/checkUserName")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResultBody checkUserName(@RequestBody SysUser sysUser) {
        if (sysUserService.getByAccount(sysUser.getAccount()) == null) {
            return ResultBody.ok();
        } else {
            return ResultBody.error();
        }
    }


    /**
     * 添加或者修改
     *
     * @param user
     * @return
     */
    @PutMapping
    public ResultBody updateById(@RequestBody @Valid SysUser user) {
        if (user.getId() != null) {
            user.setUpdateBy(user.getAccount());
            user.setUpdateTime(new Date());
            user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
            sysUserService.updateById(user);
            return ResultBody.ok().data("user", user).message(CodeConfig.UPDATE_SUCCESS.message);
        }
        return ResultBody.error();
    }

    /**
     * 修改密码
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/updateUserPwd")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResultBody updateUserPwd(@RequestBody SysUser sysUser) {
        SysUser currentUser = sysUserService.getById(sysUser.getId());
        currentUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getNewPassword()));
        sysUserService.updateById(currentUser);
        return ResultBody.ok();
    }

    /**
     * 更新status状态
     *
     * @param id
     * @param status
     * @return
     */
    @PutMapping("/updateStatus/{id}/status/{status}")
    public ResultBody updateStatus(@PathVariable(value = "id") Integer id, @PathVariable(value = "status") String status) {
        SysUser user = sysUserService.getById(id);
        user.setStatus(status);
        sysUserService.saveOrUpdate(user);
        return ResultBody.ok().message(CodeConfig.SUCCESS.message);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResultBody findById(@PathVariable(value = "id") Integer id) {
        SysUser sysUser = sysUserService.getById(id);
        Map<String, Object> map = new HashMap<>();
        map.put("sysUser", sysUser);
        return ResultBody.ok().data(map);
    }

    /**
     * 重置密码
     *
     * @param id
     * @return
     */
    @PutMapping("/resetPassword/{id}")
    public ResultBody resetPassword(@PathVariable(value = "id") Integer id) {
        SysUser user = sysUserService.getById(id);
        user.setPassword(bCryptPasswordEncoder.encode(Constant.DEFAULT_PASSWORD));
        user.setUpdateTime(new Date());
        sysUserService.updateById(user);
        return ResultBody.ok().message(CodeConfig.UPDATE_SUCCESS.message);
    }


    /**
     * 用户角色授权
     *
     * @param userId
     * @param roleIds
     * @return
     */
    @Transactional
    @PostMapping("/grantRole/{userId}")
    @PreAuthorize("hasAuthority('system:user:role')")
    public ResultBody grantRole(@PathVariable("userId") Long userId, @RequestBody Long[] roleIds) {
        List<SysUserRole> userRoleList = new ArrayList<>();
        Arrays.stream(roleIds).forEach(r -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setRoleId(r);
            sysUserRole.setUserId(userId);
            userRoleList.add(sysUserRole);
        });
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id", userId));
        sysUserRoleService.saveBatch(userRoleList);
        return ResultBody.ok();
    }
}
